home *** CD-ROM | disk | FTP | other *** search
- /*
- ** OpenURL-Handler - Asynch ARexx handler for openurl.library
- ** Written by Troels Walsted Hansen <troels@thule.no>
- ** Placed in the public domain.
- **
- ** This is the one and only source file for the handler.
- */
-
- #include <proto/exec.h>
-
- #include <clib/dos_protos.h>
- #include <clib/rexxsyslib_protos.h>
-
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/rexxsyslib_pragmas.h>
-
- #include <exec/memory.h>
- #include <rexx/rxslib.h>
- #include <rexx/errors.h>
-
- #include <string.h>
-
- #include "handler.h"
-
- #define SAVEDS __saveds
-
- extern void kprintf(const char *, ...);
-
- /**************************************************************************
- *
- * Prototypes for library and Local, non-library functions.
- *
- */
-
- VOID SAVEDS HandlerProcessEntry(VOID);
- static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd);
-
- /**************************************************************************
- *
- * Definitions and global variables.
- *
- */
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase = NULL;
- struct RxsLib *RexxSysBase = NULL;
- static const char *version = "$VER: OpenURL-Handler 1.0 " __AMIGADATE__;
-
- /**************************************************************************
- *
- * This function will be called when the handler is started.
- *
- */
-
- VOID SAVEDS HandlerProcessEntry(VOID)
- {
- struct Process *me;
- struct HandlerMsg *starthm = NULL;
- struct SignalSemaphore *ss;
- ULONG sigs, sigmask, msgcount = 0;
- struct MsgPort *mp = NULL;
- struct Message *msg;
-
- SysBase = *(struct ExecBase **)4;
- me = (struct Process *)FindTask(NULL);
-
- /* get startupmsg */
-
- while(!starthm)
- {
- /* should the handler accidentally be launched from somewhere other
- than the library, it can be broken with CTRL-C */
-
- sigs = Wait((1 << me->pr_MsgPort.mp_SigBit) | SIGBREAKF_CTRL_C);
- if(sigs &Â SIGBREAKF_CTRL_C) return;
- starthm = (struct HandlerMsg *)GetMsg(&me->pr_MsgPort);
- }
-
- ss = starthm->hm_Semaphore;
- ObtainSemaphore(ss);
-
- /* initialise everything */
-
- if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
- goto done;
-
- if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
- goto done;
-
- if(!(mp = CreateMsgPort()))
- goto done;
-
- /* reply startup msg to signal readyness */
-
- starthm->hm_Success = TRUE;
- starthm->hm_MsgPort = mp;
- ReplyMsg((struct Message *)starthm);
- starthm = NULL;
-
- /* enter input loop */
-
- sigmask = (1 << mp->mp_SigBit) | SIGBREAKF_CTRL_C;
-
- for(;;)
- {
- sigs = Wait(sigmask);
-
- if(sigs & SIGBREAKF_CTRL_C) break;
- else
- {
- while((msg = GetMsg(mp)))
- {
- if(msg->mn_Node.ln_Type == NT_REPLYMSG)
- {
- DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
- DeleteRexxMsg((struct RexxMsg *)msg);
- msgcount--;
- }
- else
- {
- struct HandlerMsg *hm = (struct HandlerMsg *)msg;
-
- if(hm->hm_Type == HMT_AREXX)
- {
- hm->hm_Success = SendRexxMsg(mp, hm->hm_ARexxPort, hm->hm_ARexxCmd);
- if(hm->hm_Success) msgcount++;
- }
-
- ReplyMsg(msg);
- }
- }
- }
- }
-
- done:
- /* release semaphore to indicate we're no longer running.
- this will stop the library from sending any more msgs */
-
- ReleaseSemaphore(ss);
-
- /* wait for return of all msgs */
-
- while(msgcount)
- {
- WaitPort(mp);
-
- while((msg = GetMsg(mp)))
- {
- if(msg->mn_Node.ln_Type == NT_REPLYMSG)
- {
- DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
- DeleteRexxMsg((struct RexxMsg *)msg);
- msgcount--;
- }
- else
- {
- ((struct HandlerMsg *)msg)->hm_Success = FALSE;
- ReplyMsg(msg);
- }
- }
- }
-
- /* empty out msgport */
-
- while((msg = GetMsg(mp)))
- {
- ((struct HandlerMsg *)msg)->hm_Success = FALSE;
- ReplyMsg(msg);
- }
-
- /* free resources */
-
- if(mp) DeleteMsgPort(mp);
- CloseLibrary((struct Library *)RexxSysBase);
- CloseLibrary((struct Library *)DOSBase);
-
- /* the startup msg needs to be replied now if a resource
- allocation failed */
-
- if(starthm)
- {
- starthm->hm_Success = FALSE;
- ReplyMsg((struct Message *)starthm);
- }
- }
-
- /**************************************************************************/
-
- static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd)
- {
- struct RexxMsg *rxmsg;
-
- if((rxmsg = CreateRexxMsg(replyport, NULL, NULL)))
- {
- rxmsg->rm_Action = RXCOMM | RXFF_STRING | RXFF_NOIO;
-
- /* create the arg string */
-
- if((rxmsg->rm_Args[0] = CreateArgstring(rxcmd, strlen(rxcmd))))
- {
- struct MsgPort *targetport;
-
- /* find the named rexx port and put the rexx msg to it */
-
- Forbid();
-
- if((targetport = FindPort(rxport)))
- {
- PutMsg(targetport, (struct Message *)rxmsg);
- Permit();
- return(TRUE);
- }
-
- Permit();
-
- DeleteArgstring(rxmsg->rm_Args[0]);
- }
- DeleteRexxMsg(rxmsg);
- }
-
- return(FALSE);
- }
-